package com.xiaoshuidi.cloud.module.contract.service.bill;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaoshuidi.cloud.framework.common.pojo.PageResult;
import com.xiaoshuidi.cloud.module.contract.controller.admin.bill.vo.CompanyCustomerBillDetailResp;
import com.xiaoshuidi.cloud.module.contract.controller.admin.bill.vo.CompanyCustomerBillPageReq;
import com.xiaoshuidi.cloud.module.contract.controller.admin.bill.vo.CompanyCustomerBillPageResp;
import com.xiaoshuidi.cloud.module.contract.convert.bill.RentOrderConvert;
import com.xiaoshuidi.cloud.module.contract.dal.dataobject.bill.RentOrderDO;
import com.xiaoshuidi.cloud.module.contract.dal.mysql.bill.RentOrderMapper;
import com.xiaoshuidi.cloud.module.contract.dal.mysql.contract.CustomerCompanyMapper;
import com.xiaoshuidi.cloud.module.contract.enums.bill.OrderPayStatusEnum;
import com.xiaoshuidi.cloud.module.contract.enums.bill.OrderTypeEnum;
import com.xiaoshuidi.cloud.module.contract.enums.contract.CompanyContractOrderShareTypeEnum;
import com.xiaoshuidi.cloud.module.contract.enums.contract.ContractStatusEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author Feng
 * @date 2023/7/3
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class CompanyCustomerBillServiceImpl implements CompanyCustomerBillService {

    private final CustomerCompanyMapper customerCompanyMapper;
    private final RentOrderMapper rentOrderMapper;

    @Override
    public PageResult<CompanyCustomerBillPageResp> page(CompanyCustomerBillPageReq req) {
        Page<CompanyCustomerBillPageResp> page = Page.of(req.getPageNo(), req.getPageSize());
        QueryWrapper<CompanyCustomerBillPageReq> wrapper = Wrappers.query();
        wrapper.in(" cr.contract_status ", CollectionUtil.newArrayList(ContractStatusEnum.ACTIVE.getCode(), ContractStatusEnum.CHECK_IN.getCode()))
                .eq("cr.deleted", false)
                .isNotNull("cc.id")
                .eq("cc.customer_company_id", req.getCustomerCompanyId())
                .like(CharSequenceUtil.isNotEmpty(req.getRoomName()), "cr.room_name", req.getRoomName());
        customerCompanyMapper.customerCompanyBillPage(page, wrapper);
        List<CompanyCustomerBillPageResp> records = page.getRecords();
        if (CollectionUtil.isNotEmpty(records)) {
            List<Long> ids = records.stream().map(s -> s.getId()).collect(Collectors.toList());
            QueryWrapper<RentOrderDO> rentOrderWrapper = Wrappers.query();
            rentOrderWrapper
                    .in("business_id", ids)
                    .eq("deleted", false);
            List<CompanyCustomerBillPageResp> resps = customerCompanyMapper.billPeriod(rentOrderWrapper);
            Map<Long, CompanyCustomerBillPageResp> map = resps.stream().collect(Collectors.toMap(CompanyCustomerBillPageResp::getId, Function.identity()));
            records.forEach(s -> {
                CompanyCustomerBillPageResp resp = map.get(s.getId());
                if (resp != null) {
                    s.setPeriods(resp.getPeriods());
                    s.setPaymentPeriod(resp.getPaymentPeriod());
                    s.setOrderShareMethodStr(CompanyContractOrderShareTypeEnum.getMsgByCode(s.getOrderShareMethod()));
                }
            });
        }
        PageResult<CompanyCustomerBillPageResp> result = new PageResult<>(records, page.getTotal());
        return result;
    }

    @Override
    public List<CompanyCustomerBillDetailResp> billDetail(Long businessId) {
        LambdaQueryWrapper<RentOrderDO> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(RentOrderDO::getBusinessId, businessId)
                .eq(RentOrderDO::getOrderType, OrderTypeEnum.DEFAULT.getCode());
        List<RentOrderDO> orders = rentOrderMapper.selectList(wrapper);
        List<CompanyCustomerBillDetailResp> list = orders.stream().map(s -> {
            CompanyCustomerBillDetailResp resp = RentOrderConvert.INSTANCE.convert2BillDetail(s);
            resp.setPayStatus(OrderPayStatusEnum.getMsgByCode(s.getPayStatus()));
            return resp;
        }).collect(Collectors.toList());
        return list;
    }
}
